pub mod calculate;
pub mod ind;

pub struct Matrix<T> {
    _row: usize,
    _col: usize,
    pub data: Vec<Vec<T>>,
}

pub trait IIorF {
    fn to_f64(&self) -> f64;
}
impl IIorF for i64 {
    fn to_f64(&self) -> f64 {
        return *self as f64;
    }
}

impl IIorF for f64 {
    fn to_f64(&self) -> f64 {
        return *self as f64;
    }
}

impl Matrix<f64> {
    pub fn from<T, D>(data: &[T]) -> Matrix<f64>
    where
        T: AsRef<[D]>,
        D: IIorF,
    {
        let mut res = Matrix {
            _row: data.len(),
            _col: data[0].as_ref().len(),
            data: vec![vec![0.0; data[0].as_ref().len()]; data.len()],
        };

        for i in 0..data.len() {
            for j in 0..data[0].as_ref().len() {
                res.data[i][j] = data[i].as_ref()[j].to_f64();
            }
        }
        res
    }

    pub fn new(row: usize, col: usize) -> Matrix<f64> {
        Matrix {
            _row: row,
            _col: col,
            data: vec![vec![0.0; col]; row],
        }
    }

    pub fn from_vec(data: Vec<Vec<f64>>) -> Matrix<f64> {
        Matrix {
            _row: data.len(),
            _col: data[0].len(),
            data: data,
        }
    }

    pub fn show(&self) {
        for i in 0..self._row {
            for j in 0..self._col {
                print!("{:.2}\t", self.data[i][j]);
            }
            println!();
        }
    }
}
